package com.example.shiro02.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import net.sf.ehcache.Ehcache;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Version 1.0
 * @Author:zlf
 * @Date:2020/11/23 - 15:26
 * @Content:
 */
@Configuration
public class ShiroConfig {

    //配置shiro的方言
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }




    //使得shiro注解支持的生效
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }


    //配置spring对shiroz注解的支持
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;//advisor相当于注解的加载器，使得spring 支持shiro的注解授权
    }

   //密码加密处理
    @Bean
    public HashedCredentialsMatcher getHashedCredentialsMatcher(){
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //matcher 用来指定加密规则
        matcher.setHashAlgorithmName("md5");//加密方式为MD5
        matcher.setHashIterations(1);//Hash加密算法的循环次数
        return matcher;
    }

    //配置自定义Realm
    @Bean
    public CustomizeRealm getCustomizeRealm(HashedCredentialsMatcher matcher){
        CustomizeRealm customizeRealm =new CustomizeRealm();
        customizeRealm.setCredentialsMatcher(matcher);//将加密规则封装到到Realm中
        return customizeRealm;

    }

    //配置缓存管理器
    @Bean
    public EhCacheManager getEhCacheManager(){
        EhCacheManager cacheManager=new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return cacheManager;
    }

    //配置默认的session管理器
    @Bean
    public DefaultWebSessionManager getDefaultWebSessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        System.out.println("----------"+sessionManager.getGlobalSessionTimeout());
        //配置sessionManager
        sessionManager.setGlobalSessionTimeout(5*60*1000);//5分钟，单位是ms
        return sessionManager;
    }
    //设置RememberMe缓存管理器
    @Bean
    public CookieRememberMeManager getCookieRememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        SimpleCookie simpleCookie = new SimpleCookie("rememberme");
        simpleCookie.setMaxAge(30*24*60*60);//设置Cookie存放时间为30天
        cookieRememberMeManager.setCookie(simpleCookie);
        return cookieRememberMeManager;


    }

    //配置SecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(CustomizeRealm customizeRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //securityManager要完成校验，需要realm
        securityManager.setRealm(customizeRealm);
        //设置缓存管理器
        securityManager.setCacheManager(getEhCacheManager());
        //设置自定义session
        securityManager.setSessionManager(getDefaultWebSessionManager());
        //设置RememberMe管理器
        securityManager.setRememberMeManager(getCookieRememberMeManager());
        return securityManager;
    }

    //配置过滤器，shrio配置的关键地方
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        //过滤器就是shiro进行权限校验的核心，进行认证和授权需要SecurityManager
        filter.setSecurityManager(securityManager);

        //设置shiro的拦截规则
        //anon  匿名用户可访问的url/未授权可访问
        //authc 认证用户可访问的url
        //user  使用RememberMe的用户可访问
        //perms 对应权限可访问
        //role  对应的角色可访问
        //user  记住我可访问的URL
        Map<String,String> filtermap = new HashMap<>();
        filtermap.put("/","anon");
        filtermap.put("/index.html","anon");
        filtermap.put("/login.html","anon");
        filtermap.put("/regist.html","anon");
        filtermap.put("/user/login","anon");
        filtermap.put("/user/regist","anon");
        filtermap.put("/**","authc");
        filtermap.put("/logout","logout");//退出登录

        //访问某个路径必须要有某个权限才可以
        filtermap.put("/c_add.html","perms[sys:c:save]");

        filter.setFilterChainDefinitionMap(filtermap);
        //设置未被授权访问的页面
        filter.setUnauthorizedUrl("/lesspermission.html");


        return filter;
    }

}
